<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>

</body>
<script>
	// * **默认绑定** ：常用的函数调用类型：独立函数调用
	// * 可以把这个规则看作是无法应用其他规则的时候默认的规则，基本指向的是window
	// function fn(){
	// 	console.log(this);// window
	// }
	// fn();
	
	
	
	// * **隐式绑定** ：如果函数调用时，前面存在调用它的对象，那么this就会隐式绑定到这个对象上
	// * 当函数引用有上下文对象的时候（obj），隐式绑定规则会把函数中的this绑定到这个上下文对象上
	// const obj = {
	// 	fn(){
	// 		console.log("fn",this===obj);// fn true
	// 	}
	// }
	// obj.fn();
	
	// * 隐式绑定可能会出现隐式丢失的问题 ：被隐式绑定的函数，会丢失了绑定对象
	// const obj ={
	// 	fn(){
	// 		console.log("fn",this);
	// 	}
	// }
	// const run = obj.fn;
	// run();
	
	
	
	
	// * **显式绑定**： 指我们通过call、apply以及bind方法改变this的行为，相比隐式绑定，我们能清楚的感知 this 指向变化过程。
	// const obj = {
	// 	userName:"obj",
	// 	fn(){
	// 		console.log("obj->fn",this===obj2,this.userName);
	// 	}
	// }
	// const obj2={
	// 	userName:"obj2"
	// }
	// // obj.fn();// 隐式绑定
	// // obj.fn.call(obj2);// 显式绑定
	// // obj.fn.apply(obj2);// 显式绑定
	// obj.fn.bind(obj2)();// 显式绑定
	
	
	
	// * **`new`绑定**：构造函数只是一些使用new操作符被调用的函数,使用new调用函数的时候，会构造一新的对象，
	// 这个时候 就把新的对象绑定给了函数的this上
	
	// function Box(){
	// 	setTimeout(()=>{
	// 		console.log(this===obj);
	// 	})
	//
	// }
	// const obj = new Box();
	
	
	// 面试题：
	function Box(){
		this.arr = [1,2,3,4];
	};
	Box.prototype.run = function(){
		console.log(this===obj);
		this.arr.map(function(){
			console.log(this);// window
		})
		
		function fn(){
			console.log("fn",this);
		}
		fn();
		
		const run = ()=>{
			console.log("run",this===obj);
		}
		run();
		
		const obj2 = {
			run:()=>{
				console.log("run",this===obj);
			}
		}
		obj2.run();
	}
	const obj = new Box();
	obj.run();
	
</script>
</html>